// 基于 axios 封装请求模块
import ajax from 'axios'
import Notify from '@/ui/Notify'
import router from '@/router'
import { getToken } from './token'
import { getStorage } from './storage'
// 新建一个 axios 实例
const axios = ajax.create({
  baseURL: 'http://toutiao.itheima.net' // 基地址
})

// 添加响应拦截器
axios.interceptors.response.use(async response => response// 当状态码为2xx/3xx开头的进这里
  , async error => { // 响应状态码4xx/5xx进这里
  // 对响应错误做点什么
    if (error.response.status === 401) { // 身份过期
      // 方式一：清除 token，强制跳转登陆页，用户有感知
      // router.currentRoute 相当于在vue文件内this.$route ->当前路由对象信息
      // fullPath，路由对象里完整路由路径#后面的一切
      Notify({ type: 'warning ', message: '身份已过期' })
      localStorage.clear()
      router.replace({
        path: '/login',
        query: { path: router.currentRoute.fullPath }
      })

      // 方式二：使用 refresh_token 换回新的 token 再继续使用，js 代码实现，用户无感知（体验好）
      /* const token = (await refreshTokenAPI()).data.data.token
      setToken(token)
      error.config.headers.Authorization = token
      axios(error.config) */
    }
    // 刷新 token 失效，无法续签，只能重新登录
    if (error.response.status === 500) {
      if (error.config.url === '/v1_0/authorizations' && error.config.method === 'put') {
        Notify({ type: 'warning ', message: '身份已过期' })
        localStorage.clear()
        router.replace('/login')
      }
    }
    return Promise.reject(error)
  })

// 添加请求拦截器
axios.interceptors.request.use(config => {
  /**
   * * 添加请求头未生效，找了很久没找到原因，在这进行暴力解决
   * todo 原因：刷新token接口添加请求头未生效
   * ? 解决：在请求拦截器中判断 config.url 和 config.method，确认是请求刷新token，再往请求头中添加数据
   * ! 罪魁祸首：在导出 axios 函数时给了 headers 默认值 {}，导致覆盖了新设置的 headers
    */
  if (config.url === '/v1_0/authorizations' && config.method === 'PUT') {
    config.headers.Authorization = 'Bearer ' + getStorage('refresh_token')
  }
  if (getToken()?.length > 0 && config.headers.Authorization === undefined) {
    // 发起请求之前, 把token携带在请求头上(表明自己身份)
    config.headers.Authorization = 'Bearer ' + getToken()
  }
  return config
}, error => Promise.reject(error))

// 导出自定义函数，参数对象解析赋值
export default (obj) => {
  return axios({
    method: 'GET',
    ...obj
    // headers: {}    // 罪魁祸首
  })
}
